package java.classe;

import java.Metodo;
import java.atributo.Atributo;
import java.pacote.Pacote;
import java.recurso.Recurso;
import java.util.ArrayList;

public abstract class ClasseEntidade implements TokensSource {
	public abstract String codigoFonte();

	protected String nome = null;

	ListaClasse classes = null;

	ListaMetodo metodos = null;

	protected boolean abstrata = false;

	protected boolean fim = false;

	protected String modificador = null;

	protected Pacote pacote = null;

	protected ListaRecurso recursos = null;

	protected ListaConstrutor construtores;

	ListaImplementa qualidades = null;

	protected Classe extende;

	protected  ListaAtributos atributos;

	protected ClasseEntidade(String nomeDaClasse) {
		this.nome = nomeDaClasse;
	}

	public String getNome() {
		return this.nome;
	}

	public void setPacote(Pacote pacote) {
		this.pacote = pacote;
	}

	public Pacote getPacote() {
		return this.pacote;
	}

	public void setAbstrata(boolean abstrata) {
		this.abstrata = abstrata;
	}

	public void setModificador(String modificador) {
		this.modificador = modificador;
	}

	public void setFinal(boolean fim) throws Exception {
		if (this.abstrata)
			throw new Exception();
		this.fim = fim;
	}

	public void addAtributo(Atributo atributo) {
		atributos = atributos == null ? new ListaAtributos()
				: atributos;
		atributos.add(atributo);

	}

	public void addMetodo(Metodo metodo) {
		metodos = metodos == null ? new ListaMetodo() : metodos;
		metodos.add(metodo);
	}

	public void addRecurso(Recurso recurso) {
		recursos = recursos == null ? new ListaRecurso() : recursos;
		recursos.add(recurso);
	}

	public String getModificador() {
		return modificador;
	}

	public void addConstrutor(Construtor construtor) {
		construtores = construtores == null ? new ListaConstrutor()
				: construtores;
		construtores.add(construtor);

	}

	class ListaConstrutor extends ArrayList<Construtor> {
		private static final long serialVersionUID = 707563633158546L;

		String codigoFonte() {
			String s = NONVALUE;
			for (Construtor c : this) {
				s += c.codigoFonte();
			}
			return s;
		}
	}

	class ListaImplementa extends ArrayList<Interface> {
		private static final long serialVersionUID = 70754432333158546L;

		String codigoFonte() {
			String s = get(0).getNome();
			for (int i = 1; i < size(); i++) {
				s += VIRGULA + ESPACO + get(i).getNome();
			}
			return s;
		}
	}

	class ListaRecurso extends ArrayList<Recurso> {
		private static final long serialVersionUID = 7073528663653158546L;

		String codigoFonte() {
			String s = NONVALUE;
			for (Recurso r : this) {
				s += r.codigoFonte() + FIMCOMANDO;
			}
			return s;
		}
	}

	class ListaMetodo extends ArrayList<Metodo> {
		private static final long serialVersionUID = 4765042117182008534L;

		String codigoFonte() {
			String s = "";
			for (Metodo m : this) {
				s += m.codigoFonte();
			}
			return s;
		}
	}

	class ListaClasse extends ArrayList<Classe> {
		private static final long serialVersionUID = 4765060452324L;

		String codigoFonte() {
			String s = "";
			for (Classe m : this) {
				s += m.codigoFonte();
			}
			return s;
		}
	}

	public void addClasse(Classe classe) {
		this.classes = classes == null ? new ListaClasse() : classes;
		classes.add(classe);
	}

	public void setEstender(Classe extende) {
		this.extende = extende;

	}

	public void addImplements(Interface qualidade) {
		qualidades = qualidades == null ? new ListaImplementa() : qualidades;
		qualidades.add(qualidade);
	}

	class ListaAtributos extends ArrayList<Atributo> {
		private static final long serialVersionUID = -1301288088683762566L;
		String codigoFonte() {
			String s = NONVALUE;
			for (Atributo atributo : this)
				s += atributo.codigoFonte() + (atributo.isFimComando()?NONVALUE:FIMCOMANDO);
			return s;
		}
	}
}
